Conversation
Убрал loop из -main.
otus-06/src/otus_06/homework.clj
Outdated
| ;; корректно прочитать "123-456" "123 jonh" и т.п. | ||
| ;; Решил обойти таким образом. | ||
| ;; Буду благодарен за подсказку | ||
| (if (re-matches #"\d+\.*\d*" s) |
There was a problem hiding this comment.
не совсем понял для чего в этом месте используется регулярка.
у вас ведь есть схема для всех полей в :field-type так? можно например используя эту информацию парсить строки с помощью функций parseInt и parseDouble. Только надо будет в try catch завернуть на случай ошибок
There was a problem hiding this comment.
Если честно не нашел функций parseInt и parseDouble.
Сначала была именно такая задумка. Но потом решил пойти таким путем и мне кажется он проще.
а :field-type это уже артефакт скорее
There was a problem hiding this comment.
я имел ввиду эти функции
(Integer/parseInt "1")
(Double/parseDouble "1.3")
There was a problem hiding this comment.
Я уже нашел.
Но никак не привыкну, что в Java есть все и нужно искать там. В ней я вообще не знаком
There was a problem hiding this comment.
Проверяет число или нет. Косякнул.
Правильная регулярна #"\d+\.?\d*"
Исправил.
otus-06/src/otus_06/homework.clj
Outdated
| [db table fieeld x] | ||
| (filterv #( = x (fieeld %))(get-data db table))) |
There was a problem hiding this comment.
вижу что find-row используется в связке с first, но при этом filterv зарелизит всю коллекцию сразу,
если оставить просто filter то результатом будет lazy sequence и в связке с first обход элементов остановится на первом найденом элементе
There was a problem hiding this comment.
Не только.
find-row либо вернёт одну запись, если ищет по id, либо вернёт массив, который тут же будет релизится, что бы посчитать данные для отчета.
Имеет ли смысл тогда исправлять? first тут нужен что бы избавиться от вектора, в котором есть одна запись
otus-06/src/otus_06/homework.clj
Outdated
| arg-rows (for [r rows] | ||
| (map #(get-val db % r) args))] |
There was a problem hiding this comment.
кажется тут подошла бы функция juxt https://clojuredocs.org/clojure.core/juxt
если сделать из args набор функций то можно обойтись одним map без for
например так (map (apply juxt args) rows) и это уменьшит количество выполняемых действий: один проход по args + map по количеству rows вместо args * rows операций
There was a problem hiding this comment.
Спасибо за наводку на интересную функцию.
Но тут, вектор из ключей не два поля одной хэш-мапы, а таблица и поле из которых нужно достать значение по id.
Задача функции get-val определить из какой таблицы брать какое поле. И вернуть нужное значение
There was a problem hiding this comment.
я имел ввиду что-то вроде такого
(let [arg-functions (map #(partial get-val db %) args)
arg-rows (map (apply juxt arg-functions) rows)])arg-functions - тут будет набор функций и все они вызовутся на каждой строке
тоже самое что и вашем коде но без использования for
так не обязательно делать просто упомянул что есть еще и такая возможность
There was a problem hiding this comment.
Все, понял!
Спасибо за наводку. Использовал в тексте
| (defn -main | ||
| "Точка входа. Крутит меню и запускает нужные функции" | ||
| [] | ||
| (reduce #(%2 %1) (load-db db) (repeatedly show-menu))) |
There was a problem hiding this comment.
тут семантически больше подошел бы loop. reduce он все же про работу с коллекциями
There was a problem hiding this comment.
Вот был сначала loop :)
Но за него в последнее время ругают
There was a problem hiding this comment.
прям ругают? ))
в использовании loop/recur нет ничего плохого
мне кажется в чате как раз разговор был о том что есть ситуации когда loop действительно подходит лучше чем всё остальное (например когда вам явно нужен бесконечный цикл или когда количество итераций не определенно заранее), но есть и другие ситуации когда нужно пробежаться по коллекции или агрегировать коллекцию по какой то функции, тут есть специализированные методы (map, reduce)
Конкретно в этом случае loop выглядит идеально (мы не знаем сколько команд введёт пользователь)
There was a problem hiding this comment.
Ну засмущал Алексей :)
Первоначально и был loop.
Потом открыл для себя repeatedly
В принципе я изначально так строил приложение, что все функции меню возвращают db, которая прокидывается дальше. Поэтому это решение прямо идеально легло.
Но я помню - reduce он для данных
margintop15px
left a comment
There was a problem hiding this comment.
в целом хорошо
задумка с явной схемой базы данных ясна
не думаю что абстракций слишком уж много
всегда предпочтительнее иметь много простых функций вместо двух-трех больших функций которые делают все и сразу
| (defn create-string | ||
| "Принимает вектор значений и возвращает строку, как в файле" | ||
| [fields row] | ||
| (->> (map row fields) |
There was a problem hiding this comment.
👍 отличный подход, использовать хэш папу как функцию
There was a problem hiding this comment.
Это меня и завораживает в Clojure: почти все - функция
| (let [[promt, fmt] (get-rep-format rep)] | ||
| (println promt) | ||
| (let [name (read-line)] | ||
| (println (format fmt name (calc-report db rep name))))) |
There was a problem hiding this comment.
напрашивается ->
(-> name
(calc-report db rep)
(format fmt name)
println)читать сверху вниз зачастую легче чем справа на лево
There was a problem hiding this comment.
Согласен. Но пока не всегда подключаются в мозгу такие решения.
| (if-let [id (f-id (find-first-row db t-search f-search name))] | ||
| (let [rows (find-row db :sales f-group id) | ||
| arg-func (map #(partial get-val db %) args) | ||
| arg-rows (map (apply juxt arg-func) rows)] |
margintop15px
left a comment
There was a problem hiding this comment.
всё хорошо
спасибо за работу
work on bugs 2 work on bugs 2


Меня волнует вопрос - не слишком ли много абстракций я наделал.
Это касается вспомогательных функций для чтения данных, настроек и т.п. из БД